package gui;

import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Hashtable;
import java.util.List;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;

import Controleur.ControleurReservation;

import model.Agenda;
import model.CatalogueCategorieChambre;
import model.CategorieChambre;
import model.LigneReservation;
import model.Reservation;

import javax.swing.ListSelectionModel;
import javax.swing.JScrollPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class PanelChambre extends JPanel {
	public static final String HEADER_LISTE_RESERVATION = "Cat\u00E9gorie de chambre Qt\u00E9 Date arriv\u00E9e Date d\u00E9part";
	private Hashtable<CategorieChambre, Integer> nbChambreSelectionne;
	private JLabel lblCategorieChambre ;
	private JSpinner jspNombreChambre ;
	private SpinnerNumberModel  modelNombreChambre ;
	private JList listeReservation ;
	private JComboBox comboBoxCat ;
	private JLabel lblNombreChambre;
	private JScrollPane scrollPane;
	private JLabel lblLblligneReservation;
	private PanelDate date;
	
	public PanelChambre(final ActionListener ctrl){
		super();
		
		nbChambreSelectionne = new Hashtable<CategorieChambre, Integer>();
		
		modelNombreChambre = new SpinnerNumberModel(1,1,1,1);
		
		this.setBackground(new Color(244, 247, 252));
		this.setBounds(0, 186, 532, 217);
		this.setLayout(null);
		
		date = new PanelDate(ctrl);
		date.setLocation(0, 0);
		this.add(date);
		
		lblCategorieChambre = new JLabel("Categorie chambre");
		lblCategorieChambre.setFont(new Font("Bookman Old Style", Font.BOLD, 12));
		lblCategorieChambre.setBounds(10, 84, 151, 14);
		this.add(lblCategorieChambre);
		
		comboBoxCat = new JComboBox();
		comboBoxCat.setFont(new Font("Bookman Old Style", Font.BOLD, 12));
		comboBoxCat.setBounds(171, 83, 351, 20);
		comboBoxCat.setModel(new DefaultComboBoxModel(CatalogueCategorieChambre.getInstance().getListeCategorie().toArray()));
		comboBoxCat.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				recalculerChambreDispo();
			}
		});
		this.add(comboBoxCat);
		
		lblNombreChambre = new JLabel("Nombre chambre");
		lblNombreChambre.setFont(new Font("Bookman Old Style", Font.BOLD, 12));
		lblNombreChambre.setBounds(10, 59, 115, 14);
		this.add(lblNombreChambre);
		
		jspNombreChambre = new JSpinner();
		jspNombreChambre.setModel(modelNombreChambre);
		jspNombreChambre.setBounds(206, 61, 29, 20);
		this.add(jspNombreChambre);		
		
		scrollPane = new JScrollPane();
		scrollPane.setBounds(10, 127, 512, 77);
		add(scrollPane);
		
		listeReservation = new JList();
		scrollPane.setViewportView(listeReservation);
		listeReservation.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		listeReservation.addListSelectionListener(new ListSelectionListener() {
			
			@Override
			public void valueChanged(ListSelectionEvent arg0) {
				if (listeReservation.getSelectedIndex() >= 0) {
					ctrl.actionPerformed(new ActionEvent(listeReservation, listeReservation.getSelectedIndex(), String.valueOf(ControleurReservation.PANEL_CHAMBRE_SELECTION_LIST)));
				}
			}
		});
		
		lblLblligneReservation = new JLabel(HEADER_LISTE_RESERVATION);
		lblLblligneReservation.setBounds(10, 111, 510, 16);
		add(lblLblligneReservation);
	}
	
	/**
	 * Active ou desactive les zone editable.
	 * @param mode si on peu editer les champs false, sinon true
	 */
	public void setConsultationMode(boolean mode){	
		date.setConsultationMode(mode);
		jspNombreChambre.setEnabled(!mode);
		comboBoxCat.setEnabled(!mode);
	}
	
	/**
	 * cree un ligne de reservation a partir des donnee fournie.
	 * @return une LingeReservation valide
	 */
	public LigneReservation creerLigneReservation(){
		Calendar tmpDateArr = date.getDateArrivee();
		Calendar tmpDateDep= date.getDateDepart();
		CategorieChambre catChambre = null;
		boolean ok = true;
		int qte =((SpinnerNumberModel)(jspNombreChambre.getModel())).getNumber().intValue();
		
		catChambre = CatalogueCategorieChambre.getInstance().find(comboBoxCat.getSelectedIndex()+1);
		
		if(tmpDateArr.get(Calendar.YEAR) - tmpDateDep.get(Calendar.YEAR) > 0){
			ok = false;
		}
		else if((tmpDateArr.get(Calendar.MONTH) > tmpDateDep.get(Calendar.MONTH)) &&
				(((tmpDateArr.get(Calendar.YEAR) - tmpDateDep.get(Calendar.YEAR)) == 0)
					  		||((tmpDateDep.get(Calendar.YEAR) - tmpDateArr.get(Calendar.YEAR)) > 1))){
				ok = false;
		}
		else if((tmpDateArr.get(Calendar.DAY_OF_MONTH) >= tmpDateDep.get(Calendar.DAY_OF_MONTH)) && 
				(tmpDateArr.get(Calendar.YEAR) == tmpDateDep.get(Calendar.YEAR)) && 
				(tmpDateArr.get(Calendar.MONTH) == tmpDateDep.get(Calendar.MONTH))){
			ok = false;
		}
		else if (catChambre == null){
			ok = false;
		}
		
		if (ok == false){
			return null;
		}
		
		int nbChambreDispo = qte;
		if(nbChambreSelectionne.contains(catChambre)){
			nbChambreDispo += nbChambreSelectionne.get(catChambre);
		}
		nbChambreSelectionne.put(catChambre, new Integer(nbChambreDispo));
		
		return  new LigneReservation(catChambre,tmpDateArr.getTime(),tmpDateDep.getTime(),qte);
	}
	
	/**
	 * insere les donnees de la lignede reservation a modifier
	 * @param ligne
	 */
	public void modifLigneRes(LigneReservation ligne){
		comboBoxCat.setSelectedIndex(ligne.getCategorieChambre().getID()-1);
		
		date.insererDates(ligne.getDateArrive(), ligne.getDateDepart());
		
		recalculerChambreDispo();
	}

	/**
	 * met a jour la liste de reservation
	 * @param resActuel
	 */
	public void majLigneReservation(Reservation resActuel){
		List<String> listeReservation = new ArrayList<String>();
		
		for (LigneReservation itLigne : resActuel){
			listeReservation.add(itLigne.toStringFormat());
		}
		
		this.listeReservation.setListData(listeReservation.toArray());
	}
	
	/**
	 * recalcule le spinner de nb de chambre
	 */
	public void recalculerChambreDispo(){
		CategorieChambre catChambre = CatalogueCategorieChambre.getInstance().find(comboBoxCat.getSelectedIndex()+1);
		
		int nbChambreDispo = Agenda.getInstance().nbChambresDispoDate(catChambre, date.getDateArrivee().getTime(), 
				date.getDateDepart().getTime());
		
		if(nbChambreSelectionne.containsKey(catChambre)){
			nbChambreDispo -= nbChambreSelectionne.get(catChambre);
		}
		
		modelNombreChambre = new SpinnerNumberModel(1,1,nbChambreDispo,1);
		jspNombreChambre.setModel(modelNombreChambre);
	}
}
